addEventListener 監聽、Event Bubbling 事件冒泡、Event Capturing 事件捕捉、stopPropagation 終止冒泡事件、preventDefault 取消預設、e.target 搭配 nodeName 與 keyCode 、表單中 blur, focus, click 事件、keydown 事件、mousemove, mouseleave 事件、網頁座標 ( screen、page、client )。
<input type="button" onclick="alert('Hello')" value="點擊" class='btn'>
在 HTML 中執行 JS ( 以 onclick 為例 ),不推薦的原因 :
綁定執行 onclick ,不像 HTML 中 onclick 會一直執行。onclick 中被插入惡意程式碼。btn.addEventListener('click' , function(){ },false)
addEventListener( '參數1' ,參數2 ,參數3 );
參數1 : 選擇事件,例如 "click" 亦可換為其他事件。滑鼠的各種事件可參閱 w3school - HTML DOM Events 。參數2 : function(e){} ,函式內可加入 e ,會回傳 event 事件。參數3 : false。
true : 從外層往內層找指定元素。false( 預設 ) : 指定元素往外層找,預設為 false ,所以如果沒寫就會是預設狀態。出處 : JavaScript 工程師養成直播班 - 2021 春季班影音
為什麼 let count = 0; 不能放在 function(e){} 內 ?
函式內的大括號 {} 執行完會釋放記憶體,如果不希望值因函式運算完而消失,就需要放在外層,函式內運算完就會往外送依序做加總。
出處 : JavaScript 工程師養成直播班 - 2021 春季班影音

DOM events 事件,例如滑鼠的各種事件可參閱 w3school - HTML DOM Events ,但現在不推薦在 HTML 使用 JS,因爲較老式用法有許多缺點下方會說到。
clientX,可從函式參數 e 去讀取裡面的屬性 clientX 。e ( 參數名可自訂 ),所以點擊按鈕後會把所有物件 ( MouseEvent 為物件 object ) 資訊紀錄到這個參數內。
onclick 與 addEventListener( "click" , function(e){},false) 差異 ?onclick 不能同時綁定兩個事件。如果綁定兩個事件以上,只會讀取最後一個。addEventListener( "click", function(e){}, false); 可以同時綁定多個事件。addEventListener () 中 true 與 false 差異?true ( Event Capturing 事件捕捉 )
false( Event Bubbling 事件汽泡 )
false ,所以如果沒寫就會是預設狀態。false ,點擊最近的東西來去觸發事件。.body 與 .box 為 false,點選 box 區域時會先執行哪個呢 ?false ( Event Bubbling 事件汽泡 ) : 指定元素往外找 。以範例來說,當下點的指定元素 .box 往外層找 .body → 先跳出 box 彈跳視窗再出現 body 彈跳視窗true ( Event Capturing 事件捕捉 ) : 從最外層往內找到指定元素。以範例來說,外層 .body 往內找到指定元素 .box → 先跳出 body 彈跳視窗再出現 box 彈跳視窗false ,點擊最近的東西來去觸發事件。
body 為 true , .box 為 false,點選 box 區域時會先執行哪個呢 ?.box 區域於 body 範圍內,而 body 的 addEventListener 是設定 true ( 從外層找到指定元素 ),所以會先跳 body 再跳 .box。防止監聽的元素互相衝突
當點選到重疊的元素時,只希望執行一個元素。可使用 stopPropagation 當指定元素和上層元素有重疊時,會阻止指定元素往外層找。
stopPropagation,點擊 .box 會彈出 box 與 body 視窗 ( 事件冒泡由指定元素往外執行 )。.box 加上 stopPropagation 後終止冒泡事件,點擊 .box 後就只會彈出 box 的 alert 視窗。stopPropagation 囉!常使用的情境:
preventDefault 取消預設觸發行為後,點擊 a 連結就不會轉跳到 google 頁面。e.target 可知道目前點擊的 DOM 範圍。
li 與 a 標籤,可於開發者工具看見這兩個 DOM 的範圍。console.log (e); 部分,開啟開發者工具也可以看到點擊元素的目前所在位置 target : li 。
nodeName 為 DOM 元素的節點,可搭配 e.target 使用。
出處 : JavaScript 工程師養成直播班 - 2021 春季班影音
<input type="button" value="點擊" class='btn'>
<ul class="list">
<li>標題 1</li>
<li>標題 2
<input type="button" class="btn" value="按鈕">
</li>
</ul>
const btn = document.querySelector('.btn');
const list = document.querySelector('.list');
btn.addEventListener('click', function (e) {
console.log(e.target.innerHTML); //點擊 input 因為裡面沒有 HTML 結構,所以會顯示空值。
console.log(e.target.nodeName); //INPUT
})
// 下方為點擊 li 標題2 的按鈕(下圖一)
list.addEventListener('click', function (e) {
console.log(e.target.innerHTML); //點擊 input 因為裡面沒有 HTML 結構,所以會顯示空值。
console.log(e.target.nodeName); //INPUT
})
//點擊第二個 li 的標題2文字 (下圖二)
list.addEventListener('click', function (e) {
console.log(e.target.innerHTML); //顯示 → 標題 與 input 結構
console.log(e.target.nodeName); //LI
})

// 點擊第二個 li 標題內的按鈕 button ▲ ( 圖一 )
// 點擊第二個 li 的標題文字 ▲ ( 圖二 )
<ul class="list">
<li>標題</li>
<li>標題
<input type="button" class="btn" value="按鈕">
</li>
</ul>
.list 這個 DOM。所以 ul.list > li *2 以內的範圍都會被綁定。ul.list > li *2 範圍內觸發 click,就會觸發函式。e.target.nodeName 會顯示 DOM 元素點擊到的節點為 INPUT 標籤。e.target.nodeName 與點擊到的DOM 節點是否相同,是的話就觸發大括號 {} 內的程式碼。
<select id="areaId">
<option selected disabled>請選取區域</option>
<option value="苓雅區">苓雅區</option>
<option value="前鎮區">前鎮區</option>
</select>
<ul class="list"></ul>
const country = [
{
farmer: '查理',
place: '苓雅區'
},
{
farmer: '布朗',
place: '前鎮區'
},
{
farmer: '派翠克',
place: '苓雅區'
},
]
change 時會觸發後方函式。forEach 撈出變數 country 內的陣列資料,並使用判斷式篩選,讓選單的值與 forEach 撈出的 place 相同時,列出農夫名字。
e.target.value 可撈出選單中文字欄位內的值。let str = '';,等跑完 forEach 再帶到 li 內 。
let str = ''; ,來做累加字串。list.innerHTML 。備註
list.innerHTML = str; 寫在 forEach 內與外雖然網頁皆顯示無誤,但對運行程式碼的效能考量不理想。
forEach 內運行的次數會和陣列長度一樣。forEach 外只會運行一次。focus 所在焦點blur 離開焦點focus 事件,當元素失去焦點時,會觸發 blur 事件。以表單為例,滑鼠點擊表單要輸入數字 ( 點擊了表單即觸發 focus 事件 ),但沒輸入就離開 ( 再點擊表單外的區域 ),就會觸發 blur 事件。

// 未填寫表格就點選計算中按鈕,會出現 NaN ▲
<h2>六角西餐廳 - 顧客點餐系統</h2>
<ul>
<li>
服務生 : Hello,請問你想要點甚麼 ?
</li>
<li>
顧客 : 給我
<input type="text" class="hamburgerId">
個漢堡,再
<input type="text" class="cokeId">
杯可樂。
</li>
<li>
服務生:
<button class="startCountId">計算</button>
,好的,總計是
<em class="totalId"></em>
元
</li>
</ul>
//歸戶
const hamNum = document.querySelector('.hamburgerId');
const cokeNum = document.querySelector('.cokeId');
const startCount = document.querySelector('.startCountId');
const total = document.querySelector('.totalId');
// 漢堡與可樂價錢
const hamPrice = 70;
const cokePrice = 50;
isNaN 判斷是否為數字
isNaN 函數用來判斷參數是否為特殊的非數字值 NaN,如果是就回傳 true,不是則回傳 false,要注意的是 isNaN 函數會將參數轉換成數字 ( number ),如果轉換成功就會回傳 true,失敗則回傳 false。return 和 return false 的差異為何呢 ? ( 助教回覆 )Ans :return 在函式內使用,會回傳一個值,並終止函式往下執行。return false 通常用來阻止提交表單或是繼續執行下面的程式碼。簡單來說就是阻止執行預設的行為。
.
return false;return false; 下方 1 與 2 的事情它都會做:
event.preventDefault();。event.stopPropagation();。return 回來。出處 : event.preventDefault()跟return false的差別是?
鍵盤式移動的遊戲,或互動式網站可使 keyCode
const body = document.body;
body.addEventListener('keydown', (e) => {
console.log(e.keyCode);
})
keydown 指按下鍵盤的那個剎那,任何的鍵盤按鍵按下都可以取得對應的鍵盤代碼,也就是所謂的 keyCode。keyCode。
renderCode() 把 keyCode 渲染在畫面上。
keydown 查出按鍵 1、2、3 的 keyCode。switch 做控制判斷。Document.body<body>、<table> 與其它的元素 )的進入點。Document.body 主要是「 回傳目前文件的 <body> 節點,如元素不存在則回傳 null 」,因此只有 body 能使用。mousemove 滑鼠移動到指定元素後觸發。
mouseleave 滑鼠離開指定元素後觸發。
mousemove 搭配 setAttribute 讓滑鼠進入 box 區域後,讓 box 由方形變圓形。mousemove 搭配 setAttribute 讓滑鼠進入 box 區域後,讓 box 由方形變圓形。mouseleave 讓滑鼠離開 box 區域後再變回方形。
classList.remove 刪除圓形 boxRadius,再使用 classList.add 新增回原本方形 box
// 刪除單個
document.getElementById("myDIV").classList.remove("mystyle");
// 刪除多個
document.getElementById("myDIV").classList.remove("mystyle", "anotherClass", "thirdClass");
animation 與 JS 的 mousemove 做小遊戲animation 屬性的應用可參閱 「 Day8 | Animation、Transition、Transform 動畫效果 」classListDOM 裡每個節點都有一個 classList 物件,可以使用來新增、刪除、修改節點上的 CSS 。
remove
add
toggle
可先開啟 CodePen 範例 搭配下方解說
螢幕 ( 手機、平板 、電腦等裝置 ) 解析度的座標點
pageY 座標點數字會持續增加,而 clientY 只會顯是當下瀏覽器高度的座標點。pageY 座標點數字會持續增加,而 clientY 只會顯是當下瀏覽器高度的座標點。function showPosition(e){
screenX.textContent = e.screenX;
screenY.textContent = e.screenY;
pageX.textContent = e.pageX;
pageY.textContent = e.pageY;
clientX.textContent = e.clientX;
clientY.textContent = e.clientY;
}
解說
e 為 showPosition 函式中的參數,可顯示出 showPosition 函式的所有資訊。
console.log(e) 可顯示函示的所有資訊 ▲console.log(e) 顯示的函式資訊。
screenX 為例 → e.screenX ( 亦可換 screenX 、screenY、target .. 等 ) 搭配 textContent ,可把 screen X 座標資訊顯示在網頁上。
CSS
cursor:none;
.mouseImg 使用 fixed 可以不會因為旁邊的捲軸滾動而影響到位置 → 如圖 ,但使用 absolute 就會因為卷軸滾動而讓 icon 移動到上方 如圖 。JS
如何讓圖案取代的鼠標 & 原來的鼠標同步 ?
querySelector() 只會讓第一個子元素會獲得監聽querySelector() 的特性只會抓第一筆資料做更新。
// 點選湯姆區域,Console 顯示節點為 LI ▲
e.target.nodeName 點擊區域內項目可確定是否有點擊到需要的節點。使用情境:
ul>li 為例:
ul,每個子元素 li 皆可獲得監聽。
解析:
nodeName 方式查詢到 li 們的節點為 LI 把它帶入判斷式 if 中 → if( e.target.nodeName !== 'LI' ){return} 點擊到的節點不等於 li 回傳 return
console.log() 就不執行 ) 。console.log(e.target.nodeName); 點選 li 內的湯姆與捷克, Console 出現的節點為 LI 所以判斷式內寫 !== 'LI'
<div class="box">
<ul class="boxList">
<li>01. coco</li>
<li>02. coxima</li>
</ul>
</div>
<div class="box2">
<ul class="box2List"></ul>
</div>
box2Data,點擊 .boxList>li 的文字可以 push 到空陣列中,再渲染到 .box2List 內。